package com.inray.nbs.Interceptors;

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.inray.nbs.bean.Userinfo;


public class UrlFilter implements Filter {
	@SuppressWarnings("unused")
	private FilterConfig filterConfig;
	private FilterChain chain;
	private HttpServletRequest request;
	private HttpServletResponse response;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
	}

	@Override
	public void destroy() {
		this.filterConfig = null;
	}

	@Override
	public void doFilter(ServletRequest servletRequest,
			ServletResponse servletResponse, FilterChain chain)
			throws IOException, ServletException {
		this.chain = chain;
		this.request = (HttpServletRequest) servletRequest;
		this.response = ((HttpServletResponse) servletResponse);
		String url = request.getServletPath();
		if (url == null)
			url = "";
		HttpSession session = request.getSession();
		Userinfo user = (Userinfo) session.getAttribute("user");
		if (noFileUrl(url, request)) { // 不需要判断权限的请求如登录页面，错误页面....则跳过
			chain.doFilter(request, response);
		} else if (user == null) {
			response.sendRedirect(request.getContextPath() + "/login.jsp");// 返回登录页面
		} else {
			// TODO
			// verifyUrl(url, user);// 判断当前user是否拥有访问此url的权限
			chain.doFilter(request, response);
		}
	}

	/**
	 * 
	 * @param url
	 *            当前请求的url
	 * @param user
	 *            当前登录用户
	 * @throws IOException
	 * @throws ServletException
	 */
	@SuppressWarnings("unused")
	private void verifyUrl(String url, Userinfo user) throws IOException,
			ServletException {
		// 获取user拥有的所有资源串
		Set<String> royurl = new HashSet<String>();
		// TODO 获取当前用户所拥有的全部可访问资源,这里需要从数据库查询

		if (royurl != null && royurl.size() > 0
				&& pass(royurl, url, request.getParameterMap())) {
			chain.doFilter(request, response);
		} else {
			response.setContentType("text/html;charset=GBK");
			response.getWriter()
					.println(
							"<div style='margin: 100 auto;text-align: center;"
									+ "font: bold 18px 宋体;color: #0066CC;vertical-align: middle'> Sorry,您没有权限访问该资源!</div>");
		}
	}

	/**
	 * 是否需要判断权限,如客户端浏览、登录页面则不需要判断权限
	 */
	protected boolean noFileUrl(String url, HttpServletRequest request) {
		if (url.indexOf("login") > 0 || url.indexOf("404") > 0
				|| url.indexOf("exception") > 0 || url.indexOf("error") > 0
				|| url.indexOf("getCookie") > 0) {
			return true;
		}
		return false;
	}

	/**
	 * 判断该用户是否有权请求该url
	 * 
	 * @param royurl
	 *            user拥有的授权的的url串集合
	 * @param url
	 *            当前请求的url
	 * @param reqmap
	 *            当前request的参数
	 * @return 是否通过该url
	 */

	protected boolean pass(Set<String> royurl, String url,
			Map<String, String[]> reqmap) {
		boolean match = true;
		for (Iterator<String> iter = royurl.iterator(); iter.hasNext();) {
			// 获取资源
			match = true;
			String res_string = iter.next();
			if (res_string.indexOf("*") > 0) {
				res_string = res_string.substring(0, res_string.indexOf("*"));
				if (url.substring(0, res_string.length()).equalsIgnoreCase(
						res_string)) {
					return true; // 增加通配符比较
				}
			}
			// 分割url与参数
			String[] spw = res_string.split("\\?");
			if (url.indexOf(spw[0]) < 0) {// 为了方便，没有写成spw[0].equals(url)
				match = false;
			}
			if (match && spw.length > 1) {
				String[] spa = spw[1].split("\\&"); // 分拆各参数
				for (int j = 0; j < spa.length; j++) {
					String[] spe = spa[j].split("="); // 分拆键与值
					String key = spe[0];
					String value = "";
					if (spe.length > 1) {
						value = spe[1].trim();
					}
					// 轮询
					String[] values = reqmap.get(key);
					if (values != null) {
						for (int k = 0; k < values.length; k++) {
							if (value.equalsIgnoreCase(values[k])) {
								match = true;
								break;
							}
							match = false;
						}
						if (!match) {
							break;
						}
					}
				}
			}
			if (match) {
				break;
			}
		}
		return match;
	}

}
